/* Copyright (C) 2007-2010 STS Soft

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using STSdb.Data;
using System.Diagnostics;

namespace STSdb.Plan
{
    //public class PageTable<TKey, TRecord>
    //{
    //    public uint PageSize { get; private set; }
    //    public XTable<TKey, TRecord> Table { get; private set; }
    //    public XTable<ulong, TKey> Index { get; private set; }

    //    public PageTable(XTable<TKey, TRecord> table, XTable<ulong, TKey> index, uint pageSize)
    //    {
    //        Table = table;
    //        Index = index;
    //        PageSize = pageSize;
    //    }

    //    public PageTable(XTable<TKey, TRecord> table, XTable<ulong, TKey> index)
    //        :this(table, index, 4 * table.BlockCapacity)
    //    {
    //    }

    //    private TKey BaseKeyLeftBuild(ulong baseIndex)
    //    {
    //        TKey key;
    //        bool founded;
    //        ulong idx = baseIndex;

    //        while (!(founded = Index.TryGet(idx, out key)) && idx > 0)
    //            idx -= PageSize;

    //        if (!founded)
    //            Index[idx] = key = Table.FirstRow.Key;
    //        if (idx == baseIndex)
    //            return key;

    //        idx += PageSize;
    //        foreach (var row in Table.Forward(key).Skip((int)PageSize))
    //        {
    //            if (idx % PageSize == 0)
    //            {
    //                Index[idx] = key = row.Key;
    //                if (idx == baseIndex)
    //                    break;
    //            }

    //            idx++;
    //        }

    //        return key;
    //    }

    //    private TKey BaseKeyRightBuild(ulong baseIndex)
    //    {
    //        ulong lastIndex = Count - 1;
    //        ulong offset = lastIndex % PageSize;
    //        ulong lastBaseIndex = lastIndex - offset;
    //        Debug.Assert(baseIndex <= lastBaseIndex);

    //        TKey key;
    //        bool founded;
    //        ulong idx = baseIndex;

    //        while (!(founded = Index.TryGet(idx, out key)) && idx < lastBaseIndex)
    //            idx += PageSize;

    //        if (!founded)
    //            Index[idx] = key = Table.Backward().Skip((int)offset).First().Key;
    //        if (idx == baseIndex)
    //            return key;

    //        idx -= PageSize;
    //        foreach (var row in Table.Backward(key).Skip((int)PageSize))
    //        {
    //            if (idx % PageSize == 0)
    //            {
    //                Index[idx] = key = row.Key;
    //                if (idx == baseIndex)
    //                    break;
    //            }

    //            idx--;
    //        }

    //        return key;
    //    }

    //    private TKey GetBaseKey(ulong baseIndex)
    //    {
    //        Debug.Assert(baseIndex % PageSize == 0);
    //        return (baseIndex < Count / 2) ? BaseKeyLeftBuild(baseIndex) : BaseKeyRightBuild(baseIndex);
    //    }

    //    public Row<TKey, TRecord> this[ulong index]
    //    {
    //        get
    //        {
    //            if (index >= Count)
    //                throw new ArgumentOutOfRangeException("index");

    //            if (index < Count / 2)
    //            {
    //                var row = Index.FindPrev(index);
    //                if (row == null)
    //                {
    //                }


    //                return Table.Forward(row.Record).Skip((int)(index - row.Key)).First();
    //            }
    //            else
    //            {
    //                var row = Index.FindNext(index);
    //                if (row == null)
    //                {
    //                }


    //                return Table.Backward(row.Record).Skip((int)(row.Key - index)).First();
    //            }

    //            //ulong offset = index % PageSize;
    //            //ulong baseIndex = index - offset;
    //            //TKey key = GetBaseKey(baseIndex);

    //            //return Table.Forward(key).Skip((int)offset).First();
    //        }
    //        set
    //        {
    //            //var row = this[index];
    //            //Table[row.Key] = value.Record;

    //            throw new NotImplementedException();
    //        }
    //    }

    //    public void Delete(ulong index)
    //    {
    //        throw new NotSupportedException();
    //    }

    //    public IEnumerable<Row<TKey, TRecord>> Forward(ulong fromIndex, ulong toIndex)
    //    {
    //        if (fromIndex >= Count)
    //            throw new ArgumentOutOfRangeException("fromIndex");
    //        if (toIndex >= Count)
    //            throw new ArgumentOutOfRangeException("toIndex");
    //        if (fromIndex > toIndex)
    //            throw new ArgumentException("fromIndex > toIndex");

    //        ulong offset = fromIndex % PageSize;
    //        ulong baseIndex = fromIndex - offset;
    //        TKey key = GetBaseKey(baseIndex);

    //        ulong count = toIndex - fromIndex + 1;
    //        foreach (var row in Table.Forward(key).Skip((int)offset))
    //        {
    //            yield return row;

    //            count--;
    //            if (count == 0)
    //                break;
    //        }
    //    }

    //    public IEnumerable<Row<TKey, TRecord>> Backward(ulong toIndex, ulong fromIndex)
    //    {
    //        if (fromIndex >= Count)
    //            throw new ArgumentOutOfRangeException("fromIndex");
    //        if (toIndex >= Count)
    //            throw new ArgumentOutOfRangeException("toIndex");
    //        if (fromIndex > toIndex)
    //            throw new ArgumentException("fromIndex > toIndex");

    //        ulong offset = toIndex % PageSize;
    //        ulong lastIndex = Count - 1;
    //        ulong lastBaseIndex = lastIndex - lastIndex % PageSize;

    //        TKey key;
    //        int skipCount;
    //        if (toIndex > lastBaseIndex)
    //        {
    //            key = Table.LastRow.Key;
    //            skipCount = (int)(lastIndex - toIndex);
    //        }
    //        else
    //        {
    //            key = GetBaseKey(toIndex - offset + PageSize);
    //            skipCount = (int)(PageSize - offset);
    //        }

    //        ulong count = toIndex - fromIndex + 1;
    //        foreach (var row in Table.Backward(key).Skip(skipCount))
    //        {
    //            yield return row;

    //            count--;
    //            if (count == 0)
    //                break;
    //        }
    //    }

    //    public ulong Count
    //    {
    //        get { return Table.Count; }
    //    }
    //}
}
